/**
  ETFRoot project, Anyang Normal University && IMP-CAS
  \class ETFTrackManager
  \brief a manager class holding the fitted tracks and the track finders.
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-11-01
  \date 2021-11-01 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2021-11-01   <td>Asia Sun    <td>file created                  </tr>
  </table>

  \copyright Copyright (c) 2021 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#include "ETFTrackManager.h"
#include "ETFPreTaTracker.h"
#include "ETFPostTaTracker.h"
#include "ETFPostMagTracker.h"
#include "ETFGlobalTracker.h"

ClassImp(ETFTrackManager);

ETFTrackManager *ETFTrackManager::fInstance = nullptr;

ETFTrackManager::ETFTrackManager() : ETFVTrackManager(){
  fPreTaTracker = new ETFPreTaTracker("preTaTracker");
  fPostTaTracker = new ETFPostTaTracker("postTaTracker");
  fPostMagTracker = new ETFPostMagTracker("postMagTracker");
  fGlobalTracker = new ETFGlobalTracker("globalTracker");
} // end ctor

ETFTrackManager::~ETFTrackManager(){}

void ETFTrackManager::SetDebug(bool opt){
  fPreTaTracker->SetDebug(opt);
  fPostTaTracker->SetDebug(opt);
  fPostMagTracker->SetDebug(opt);
  fGlobalTracker->SetDebug(opt);
} // end member function SetDebug

ETFTrackManager *ETFTrackManager::Instance(){
  if(!fInstance) fInstance = new ETFTrackManager();
  return fInstance;
} // end member function Instance

// register tracks to main TTree
void ETFTrackManager::Register(){
  fPreTaTracker->Register();
  fPostTaTracker->Register();
  fPostMagTracker->Register();
  fGlobalTracker->Register();
} // end member function Register

// do the overall tracking
void ETFTrackManager::Map(){
  if(!fHasMapped) fHasMapped = true;
  else return;
  // do the preliminary tracking //
  fPreTaTracker->Map();
  fPostTaTracker->Map();
  fPostMagTracker->Map();
  // then refine the tracking with ETFGlobalTracker //
  if(1 == fPostMagTracker->GetNofTracks() && fPostTaTracker->GetNofTracks() >= 1
      && fPreTaTracker->GetNofTracks() >= 1){
    fGlobalTracker->SetPostMagTrk(fPostMagTracker->GetTrack(0));
    fGlobalTracker->Map();
  } // end if
  // replace X tracks in pre/post-TaTrackers with ameliorated global ones
  if(fGlobalTracker->GetNofTracks())
    fGlobalTracker->UpdateTracks(fPreTaTracker, fPostTaTracker);
} // end member function Map

// do the overall 3D tracking
void ETFTrackManager::Map3D(){
  if(!fHasMapped3D) fHasMapped3D = true;
  else return;

  Map(); // do the 2D X tracking first, and ameliorate the tracking
  fPostMagTracker->Map3D(); // do the Y tracking altogether
} // end member function Map

void ETFTrackManager::Draw(){
  // fPreTaTracker->Draw();
  // fPostTaTracker->Draw();
  fGlobalTracker->Draw();
  fPostMagTracker->Draw();
} // end member function Draw

void ETFTrackManager::Write(){
  // fPreTaTracker->Write();
  // fPostTaTracker->Write();
  fGlobalTracker->Write();
  fPostMagTracker->Write();
} // end member function Write

void ETFTrackManager::Reset(){
  fPreTaTracker->Reset();
  fPostTaTracker->Reset();
  fGlobalTracker->Reset();
  fPostMagTracker->Reset();
  if(fHasMapped) fHasMapped = false;
  if(fHasMapped3D) fHasMapped3D = false;
} // end member function Write

void ETFTrackManager::Print(){
  fPreTaTracker->Print();
  fPostTaTracker->Print();
  fGlobalTracker->Print();
  fPostMagTracker->Print();
} // end member function Print
